#pragma once
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cassert>
#include <memory>
#include <sstream>
#include <string>

using namespace std;


template<class INFO>
/**
* Noder f&ouml;r att spara information i listan.
*/
struct Node
{
	Node<INFO>(){}
	Node<INFO>(INFO info){this->info=info;}

	INFO info;
	unique_ptr<Node<INFO>> next;

	~Node<INFO>()
	{
	}
};


template<class INFO>
/**
* Listan med iterator och tappra f&ouml;rs&ouml;k med unique_ptr.
*/
class List
{
	class Iterator
	{
	public:
		Iterator(Node<INFO> *ptr)
		{
			ptr_ = ptr;
		}
		Iterator operator++() { Iterator i = *this; ptr_=ptr_->next.get(); return i; }
		Iterator operator++(int junk) { ptr_=ptr_->next.get(); return *this; }
		Node<INFO>& operator*() { return *ptr_; }
		Node<INFO>* operator->() { return ptr_; }
		bool operator==(const Iterator& rhs) { return ptr_ == rhs.ptr_; }
		bool operator!=(const Iterator& rhs) { return ptr_ != rhs.ptr_; }

	private:
		Node<INFO>* ptr_;

	};

private:
	unique_ptr<Node<INFO>> head;
	Node<INFO> *tail;

public:

	List(void)
	{
		head = unique_ptr<Node<INFO>>(nullptr);
		tail = nullptr;
	}
	void add(INFO info)
	{
		if ( head == nullptr )
		{
			head = unique_ptr<Node<INFO>>(new Node<INFO>(info));
			tail = head.get();
		} 
		else
		{
			Node<INFO> *n = new Node<INFO>(info);
			n->next = unique_ptr<Node<INFO>>(std::move(head));
			head = unique_ptr<Node<INFO>>(n);
		}
	}


	/**
	* L&auml;ser fr&aring;n fil, kollar om talet redan finns i listan och beslutar vad som ska ske med talet.
	*/
	void read4life(string textfile)
	{
		int temp = 1;
		ifstream filein;
		INFO number;
		filein.open(textfile);
		while(!filein.eof())
		{
			filein >> number;
			if(temp == 1)
			{
				add(number);
				temp = 0;
			}
			else
			{
				for( auto it = begin(); it != end(); it++)
				{
					if(number==(*it).info)
					{
						temp = 2;
					}
				}
				if(temp==0)
					add(number);
				temp = 0;
			}//end else
		}//end while
		filein.close();
	}//end func

	/**
	* Gjorde en specialare :D
	*/
	static void read4life2(List<INFO>& even, List<INFO>& uneven, string textfile)
	{
		int temp, temp2;
		temp = temp2 = 1;
		ifstream filein;
		INFO number;
		filein.open(textfile);
		while(!filein.eof())
		{
			filein >> number;
			if(number % 2 == 0)
			{
				if (temp != 1)
				{
					for( auto it = even.begin(); it != even.end(); it++)
					{
						if(number==(*it).info)
						{
							temp = 2;
						}
					}
					if(temp==0)
						even.add(number);
					
				}
				else
					even.add(number);
				temp = 0;
			}
			else
			{
				if (temp2 != 1)
				{
					for( auto it = uneven.begin(); it != uneven.end(); it++)
					{
						if(number==(*it).info)
						{
							temp2 = 2;
						}
					}
					if(temp2 == 0)
						uneven.add(number);
					
				}
				else
					uneven.add(number);
				temp2 = 0;
			}
		}//end while
		filein.close();
	}//end func

	string str()
	{
		ostringstream oss;
		Node<INFO> *n = head.get();
		if( n == nullptr )
			return "tom";
		else
		{
			do
			{
				oss << n->info << "\n";
				n = n->next.get();
			}while ( n != nullptr );
		}

		return oss.str();
	}
	~List(void)
	{
	}
	Iterator begin()
	{
		return Iterator(head.get());
	}

	Iterator end()
	{
		return Iterator(nullptr);
	}
};

